﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using MyKeyValueCollection;

namespace MyKeyValueCollection.Tests
{
    [TestFixture]
    public class UT_MyKeyValuePairList
    {
        [SetUp]
        public void SetUp()
        {
            list = new MyKeyValuePairList();
        }

        [TestCase(3, "3", 2)]
        [TestCase(7, "text", -1)]
        public void TestForIndexOf(int key, string value, int indexActual)
        {
            list = new MyKeyValuePairList(arr);
            MyKeyValuePair item = new MyKeyValuePair(key, value);
            int indexExpected = list.IndexOf(item);

            Assert.AreEqual(indexActual, indexExpected);
        }

        [TestCase(0, 5, "5")]
        [TestCase(2, 5, "5")]
        [TestCase(3, 5, "5")]
        public void TestForInsert(int index, int key, string value)
        {
            MyKeyValuePair itemToInsert = new MyKeyValuePair(key, value);
            list = new MyKeyValuePairList(arr);
            list.Insert(index, itemToInsert);
            MyKeyValuePair[] actualArray = new MyKeyValuePair[arr.Length + 1];
            Array.Copy(arr, actualArray, index);
            actualArray[index] = itemToInsert;
            Array.Copy(arr, index, actualArray, index + 1, arr.Length - index);

            Assert.IsTrue(list.Compare(actualArray));
        }

        [TestCase(7, 5, "5")]
        [ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void TestForInsertWithException(int index, int key, string value)
        {
            MyKeyValuePair itemToInsert = new MyKeyValuePair(key, value);
            list = new MyKeyValuePairList(arr);
            list.Insert(index, itemToInsert);
        }

        [Test]
        public void TestForRemoveAt([Values(0, 2, 3)] int index)
        {
            list = new MyKeyValuePairList(arr);
            list.RemoveAt(index);
            MyKeyValuePair[] actualArray = new MyKeyValuePair[arr.Length - 1];
            Array.Copy(arr, actualArray, index);
            Array.Copy(arr, index + 1, actualArray, index, arr.Length - index - 1);

            Assert.IsTrue(list.Compare(actualArray));
        }

        [Test]
        [ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void TestForRemoveAtWithException([Values(7, 10)] int index)
        {
            list = new MyKeyValuePairList(arr);
            list.RemoveAt(index);
        }

        [TestCase(5, "candy")]
        public void TestForAdd(int key, string value)
        {
            MyKeyValuePair itemToAdd = new MyKeyValuePair(key, value);
            list = new MyKeyValuePairList(arr);
            list.Add(itemToAdd);
            MyKeyValuePair[] actualArray = new MyKeyValuePair[arr.Length + 1];
            Array.Copy(arr, actualArray, arr.Length);
            actualArray[arr.Length] = itemToAdd;

            Assert.IsTrue(list.Compare(actualArray));
        }

        [Test]
        public void TestForClear()
        {
            list = new MyKeyValuePairList(arr);
            list.Clear();
            MyKeyValuePair[] actualArray = new MyKeyValuePair[0];

            Assert.IsTrue(list.Compare(actualArray));
        }

        [TestCase(2, "2", true)]
        [TestCase(5, "candy", false)]
        public void TestForContains(int key, string value, bool expected)
        {
            MyKeyValuePair itemToSearch = new MyKeyValuePair(key, value);
            list = new MyKeyValuePairList(arr);
            bool actual = list.Contains(itemToSearch);

            Assert.AreEqual(expected, actual);
        }

        [TestCase(2, "2", true)]
        [TestCase(5, "candy", false)]
        public void TestForRemove(int key, string value, bool expected)
        {
            MyKeyValuePair itemToRemove = new MyKeyValuePair(key, value);
            list = new MyKeyValuePairList(arr);
            bool actual = list.Remove(itemToRemove);

            Assert.AreEqual(expected, actual);
        }

        private MyKeyValuePairList list;
        private MyKeyValuePair[] arr = { new MyKeyValuePair(1, "1"), new MyKeyValuePair(2, "2"), new MyKeyValuePair(3, "3"), new MyKeyValuePair(4, "4") };
    }
}
